package com.wasion.gydpe.common.security;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.wasion.gydpe.dao.OperatorDao;
import com.wasion.gydpe.dao.ResourceDao;
import com.wasion.gydpe.dao.RoleDao;
import com.wasion.gydpe.model.Operator;
import com.wasion.gydpe.model.Role;

/**
 * 
 * @ClassName: LocalUserDetailService
 * @Description: 用户登录时调用，进行密码的验证、权限与用户的绑定
 * @author 高意
 * @date Oct 16, 2012 4:12:32 PM
 * 
 */
public class LocalUserDetailServiceImpl implements UserDetailsService {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(LocalUserDetailServiceImpl.class);

	@Resource
	private OperatorDao operatorDao;

	@Resource
	private RoleDao roleDao;

	@Resource
	private ResourceDao resourceDao;

	Map<String, Object> param = new HashMap<String, Object>();

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("username", username);

		Operator user = null;
		try {
			user = this.operatorDao.getOne(param);
		} catch (com.wasion.gydpe.exception.DataAccessException e) {
			e.printStackTrace();
			LOGGER.error("根据username查询用户失败：loadUserByUsername >>>>>> " + e);
		}

		if (user == null) {
			throw new UsernameNotFoundException(username);
		}

		Collection<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(user);

		boolean enables = true;
		boolean accountNonExpired = true;
		boolean credentialsNonExpired = true;
		boolean accountNonLocked = true;

		User userDeatail = new User(user.getUsername(), user.getPassword(),
				enables, accountNonExpired, credentialsNonExpired,
				accountNonLocked, grantedAuths);
		return userDeatail;
	}

	/**
	 * 
	 * @Title: obtionGrantedAuthorities
	 * @Description: 取得用户的权限
	 * @param
	 * @return
	 * @throws
	 */
	private Set<GrantedAuthority> obtionGrantedAuthorities(Operator user) {

		Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();

		param.clear();
		param.put("userId", user.getId());
		List<Role> roleList = null;
		try {
			roleList = this.roleDao.query(param);
		} catch (com.wasion.gydpe.exception.DataAccessException e) {
			e.printStackTrace();
			LOGGER.error("根据userId查询所有角色失败：obtionGrantedAuthorities >>>>>> "
					+ e);
		}
		Set<Role> roleSet = new HashSet<Role>();
		roleSet.addAll(roleList);

		for (Role role : roleSet) {

			param.clear();
			param.put("roleId", role.getId());
			List<com.wasion.gydpe.model.Resource> resourceList = null;
			try {
				resourceList = this.resourceDao.queryDistributeds(param);
			} catch (com.wasion.gydpe.exception.DataAccessException e) {
				e.printStackTrace();
				LOGGER.error("根据roleId查询资源失败：obtionGrantedAuthorities >>>>>> "
						+ e);
			}

			Set<com.wasion.gydpe.model.Resource> tempRes = new HashSet<com.wasion.gydpe.model.Resource>();
			tempRes.addAll(resourceList);

			for (com.wasion.gydpe.model.Resource res : tempRes) {
				authSet.add(new GrantedAuthorityImpl(res.getPermissionId()));
			}
		}
		return authSet;
	}
}